package cn.wp.common.core.authentication.util;

import cn.hutool.core.util.StrUtil;
import cn.wp.common.core.WpVar;
import cn.wp.common.core.authentication.AuthenticationProperties;
import cn.wp.common.core.authentication.Token;
import cn.wp.common.core.exception.WpException;
import cn.wp.common.core.id.Id;
import cn.wp.common.core.util.AesUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * Token 工具类型
 * Created by chenyb on 2019/09/26
 */
@Component
@Slf4j
public class TokenUtil {

    private static TokenUtil tokenUtil;

    public TokenUtil(){
        TokenUtil.tokenUtil = this;
    }

    public static TokenUtil self(){
        return tokenUtil;
    }

    @Autowired
    private AuthenticationProperties authenticationProperties;

    public Token createToken(){
        Token token = new Token();
        token.setTokenId(Id.genUUID());
        token.setTokenValue(AesUtil.encrypt(token.getTokenId(),authenticationProperties.getTokenSecret()));
        return token;
    }

    public String parseToken(String tokenValue){
        if(StrUtil.isBlank(tokenValue)){
            return null;
        };

        String str = AesUtil.decrypt(decode(tokenValue),authenticationProperties.getTokenSecret());
        if(str.length() == 32){
            return str;
        }else{
            return null;
        }
    }

    public String encode(String tokenValue){
        try {
            log.info("token = " + tokenValue);
            // 无 + / 号，说明token为无特殊字符token，直接返回
            if(tokenValue.indexOf("+") == -1 && tokenValue.indexOf("/") == -1) {
                log.info("encode.token = " + tokenValue);
                return tokenValue;
            };

            // 编码后的 + 替换
            if(tokenValue.indexOf("+") >= 0){
                tokenValue = tokenValue.replaceAll("\\+","%2B");
            }

            // 编码后的 / 替换
            if(tokenValue.indexOf("/") >=0){
                tokenValue = tokenValue.replaceAll("/","%2F");
            }

        } catch (Exception e) {
            throw new WpException("token编码出错",e);
        }

        log.info("encode.token = " + tokenValue);
        return tokenValue;
    }

    private String decode(String tokenValue){
        try {
            log.info("token = " + tokenValue);
            // 无%号，说明token未编码，直接返回
            if(tokenValue.indexOf("%") == -1) {
                log.info("decode.token = " + tokenValue);
                return tokenValue;
            };

            // 编码后的 + 替换
            if(tokenValue.indexOf("%2B") >= 0){
                tokenValue = tokenValue.replaceAll("%2B","+");
            }
            if(tokenValue.indexOf("%2b") >= 0){
                tokenValue = tokenValue.replaceAll("%2b","+");
            }

            // 编码后的 / 替换
            if(tokenValue.indexOf("%2F") >=0){
               tokenValue = tokenValue.replaceAll("%2F","/");
            }

            if(tokenValue.indexOf("%2f") >=0){
                tokenValue = tokenValue.replaceAll("%2f","/");
            }

            //tokenValue = URLDecoder.decode(tokenValue, WpVar.ENCODE);
        } catch (Exception e) {
            throw new WpException("token解码出错",e);
        }

        log.info("decode.token = " + tokenValue);
        return tokenValue;
    }
}
